
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>JVM类加载机制 - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>JVM类加载机制 - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">JVM类加载的生命周期包含哪七个阶段？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">类加载的生命周期包括加载（Loading）、验证（Verification）、准备（Preparation）、解析（Resolution）、初始化（Initialization）、使用（Using）和卸载（Unloading）七个阶段。</div>
          </div>
          <div class="card-source">来源: 类加载的生命周期</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">什么是双亲委派模型？它的主要目的是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">双亲委派模型的核心思想是：当一个类加载器收到类加载请求时，它会先将请求委派给父加载器处理，如果父加载器无法加载，再由当前加载器尝试加载。其主要目的有两个：一是避免类的重复加载，节省内存；二是保证核心类库的安全性，防止用户自定义的类替代JDK的核心类。</div>
          </div>
          <div class="card-source">来源: 双亲委派模型 -> 1. 模型概述</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">对比</div>
          <div class="card-question">请区分JVM类加载生命周期中的“准备”阶段和“初始化”阶段。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">对比</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">“准备”阶段为类的静态变量分配内存，并将其初始化为数据类型的默认值（如0、null等）。而“初始化”阶段是执行类的<clinit>方法的过程，该方法由编译器自动收集类中所有静态变量的赋值动作和静态语句块生成，是真正执行类中定义的初始化代码的阶段。</div>
          </div>
          <div class="card-source">来源: 类加载的生命周期 -> 3. 准备（Preparation） 和 5. 初始化（Initialization）</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">JVM提供了哪三种默认的类加载器，它们各自负责加载什么范围的类？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">JVM提供的三种默认类加载器分别是：1. 启动类加载器（Bootstrap ClassLoader）：负责加载Java核心类库（<JAVA_HOME>/lib目录中的类）。2. 扩展类加载器（Extension ClassLoader）：负责加载<JAVA_HOME>/lib/ext目录中的扩展库。3. 应用类加载器（Application ClassLoader）：负责加载用户应用程序的类路径（CLASSPATH）下的类。</div>
          </div>
          <div class="card-source">来源: 类加载器（ClassLoader） -> 2. 类加载器的分类</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">对比</div>
          <div class="card-question">在动态加载类时，使用`Class.forName()`和`ClassLoader.loadClass()`有何关键区别？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">对比</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">关键区别在于是否会执行类的初始化。`Class.forName()`在加载类的同时会执行其静态代码块，完成类的初始化。而`ClassLoader.loadClass()`默认只加载类，不执行静态代码块，即不进行初始化。</div>
          </div>
          <div class="card-source">来源: 类加载的三种方式 -> 2. 动态加载</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">问题排查</div>
          <div class="card-question">请解释`ClassNotFoundException`和`NoClassDefFoundError`这两个常见错误的区别。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">问题排查</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">`ClassNotFoundException`表示在运行时未能找到指定的类，通常是因为类路径配置错误或类不存在。`NoClassDefFoundError`则表示类在编译时存在，但在运行时其定义不可用，原因可能是类文件被删除、初始化失败或类加载器冲突。</div>
          </div>
          <div class="card-source">来源: 类加载的常见问题 -> 4. 类未找到（ClassNotFoundException） 和 5. 类定义不匹配（NoClassDefFoundError）</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">在类加载生命周期中，“解析”（Resolution）阶段的具体作用是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">“解析”阶段的作用是将常量池中的符号引用（Symbolic Reference），即以字符串或其他符号形式表示的逻辑引用，替换为直接引用（Direct Reference），即指向内存中实际位置的物理地址引用。</div>
          </div>
          <div class="card-source">来源: 类加载的生命周期 -> 4. 解析（Resolution）</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">什么是热加载（Hot Loading）？它如何利用类加载机制实现？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">热加载允许在JVM不关闭的情况下动态加载或更新类的实现。它通过创建新的自定义类加载器来加载新版本的类。因为JVM使用“类的全限定名 + 加载它的类加载器”作为类的唯一标识，所以新加载器加载的同名类被视为一个不同的类，从而实现了类的更新替换。</div>
          </div>
          <div class="card-source">来源: 类加载与热加载 -> 2. 热加载的概念 和 3. 类加载与热加载的关系</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">在什么条件下，JVM的垃圾回收器会卸载一个类以释放内存？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">一个类被卸载需要满足三个条件：1. 该类的所有实例都已被垃圾回收器回收。2. 加载该类的ClassLoader对象没有被引用。3. 该类的Class对象没有被引用。此外，卸载通常仅限于用户自定义类加载器加载的类。</div>
          </div>
          <div class="card-source">来源: 类加载的生命周期 -> 7. 卸载（Unloading）</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
